﻿// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. 
// See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace System.Threading.Actors.Utilities
{
    // Allows us to convert a TcpClient to an ITcpClient.
    internal class WrappedTcpClient : ITcpClient
    {
        private TcpClient m_client;
        private NetworkStream m_clientStream;
        private int m_port; // mostly for testing

        public WrappedTcpClient(string hostname, int port)
        {
            m_port = port;
            if (hostname == null && port < 0)
            {
                // For testing
                m_client = new TcpClient();
            }
            else
            {
                m_client = new TcpClient(hostname, port);
                m_client.NoDelay = true;
                m_clientStream = m_client.GetStream();
            }
        }

        public WrappedTcpClient(TcpClient originalClient)
        {
            m_client = originalClient;
            m_client.NoDelay = true;
            m_clientStream = originalClient.GetStream();
        }

        public IO.Stream InputStream
        {
            get { return m_clientStream; }
        }

        public IO.Stream OutputStream
        {
            get { return m_clientStream; }
        }

        public int Port
        {
            get { return m_port; }
        }

        public void Close()
        {
            Dispose();
        }

        public void Dispose()
        {
            if (m_clientStream != null)
            {
                m_clientStream.Dispose();
                m_clientStream = null;
            }

            if (m_client != null)
            {
                m_client.Close();
                m_client = null;
            }
        }

        //
        // A little magic to instruct our portable library to use WrappedTcpClient 
        // when creating ITcpClients.
        //
        private static ITcpClient CreateTcpClient(string hostname, int port)
        {
            return new WrappedTcpClient(hostname, port);
        }

        static WrappedTcpClient()
        {
            // This is guaranteed to replace LightupITcpClientFactory.CreateTcpClientFunc 
            // *after* it has been set to its default.  If the LightupITcpClientFactory static constructor has
            // not yet run, then it will run here, just before we change the value of
            // CreateTcpClientFunc.
            LightupITcpClientFactory.CreateTcpClientFunc = CreateTcpClient;
        }
    }
}
